<?php
/*--------------------------------------------------------------
   AdditionalOption.php 2023-06-06
   Gambio GmbH
   http://www.gambio.de
   Copyright (c) 2023 Gambio GmbH
   Released under the GNU General Public License (Version 2)
   [http://www.gnu.org/licenses/gpl-2.0.html]
 -------------------------------------------------------------*/
declare(strict_types=1);

namespace Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model;

use Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model\Events\AdditionalOptionsImageListIdUpdated;
use Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model\Events\AdditionalOptionsSortOrderUpdated;
use Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model\Events\AdditionalOptionsStockUpdated;
use Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model\Events\AdditionalOptionsValueCustomizationUpdated;
use Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model\ValueObjects\AdditionalOptionId;
use Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model\ValueObjects\AdditionalOptionStock;
use Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model\ValueObjects\ImageListId;
use Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model\ValueObjects\OptionAndOptionValueId;
use Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model\ValueObjects\OptionValueCustomization;
use Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model\ValueObjects\ProductId;
use Gambio\Core\Event\Abstracts\AbstractEventRaisingEntity;

/**
 * Class AdditionalOption
 *
 * @package Gambio\Admin\Modules\Product\Submodules\AdditionalOption\Model
 */
class AdditionalOption extends AbstractEventRaisingEntity
{
    /**
     * AdditionalOption constructor.
     *
     * @param AdditionalOptionId       $id
     * @param ProductId                $productId
     * @param OptionAndOptionValueId   $optionAndOptionValueId
     * @param ImageListId              $imageListId
     * @param OptionValueCustomization $optionValueCustomization
     * @param AdditionalOptionStock    $additionalOptionStock
     * @param int                      $sortOrder
     */
    private function __construct(
        private AdditionalOptionId       $id,
        private ProductId                $productId,
        private OptionAndOptionValueId   $optionAndOptionValueId,
        private ImageListId              $imageListId,
        private OptionValueCustomization $optionValueCustomization,
        private AdditionalOptionStock    $additionalOptionStock,
        private int                      $sortOrder = 0
    ) {
    }
    
    
    /**
     * @param AdditionalOptionId       $id
     * @param ProductId                $productId
     * @param OptionAndOptionValueId   $optionAndOptionValueId
     * @param ImageListId              $imageListId
     * @param OptionValueCustomization $optionValueCustomization
     * @param AdditionalOptionStock    $additionalOptionStock
     * @param int                      $sortOrder
     *
     * @return AdditionalOption
     */
    public static function create(
        AdditionalOptionId       $id,
        ProductId                $productId,
        OptionAndOptionValueId   $optionAndOptionValueId,
        ImageListId              $imageListId,
        OptionValueCustomization $optionValueCustomization,
        AdditionalOptionStock    $additionalOptionStock,
        int                      $sortOrder = 0
    ): AdditionalOption {
        return new static($id,
                        $productId,
                        $optionAndOptionValueId,
                        $imageListId,
                        $optionValueCustomization,
                        $additionalOptionStock,
                        $sortOrder);
    }
    
    
    /**
     * @param ImageListId $imageListId
     */
    public function changeImageListId(ImageListId $imageListId): void
    {
        $this->imageListId = $imageListId;
        $this->raiseEvent(AdditionalOptionsImageListIdUpdated::create($this->id, $imageListId));
    }
    
    
    /**
     * @param OptionValueCustomization $optionValueCustomization
     */
    public function changeOptionValueCustomization(OptionValueCustomization $optionValueCustomization): void
    {
        $this->optionValueCustomization = $optionValueCustomization;
        $this->raiseEvent(AdditionalOptionsValueCustomizationUpdated::create($this->id, $optionValueCustomization));
    }
    
    
    /**
     * @param AdditionalOptionStock $additionalOptionStock
     */
    public function changeAdditionalOptionStock(AdditionalOptionStock $additionalOptionStock): void
    {
        $this->additionalOptionStock = $additionalOptionStock;
        $this->raiseEvent(AdditionalOptionsStockUpdated::create($this->id, $additionalOptionStock));
    }
    
    
    /**
     * @param int $sorOrder
     */
    public function changeSortOrder(int $sorOrder): void
    {
        $this->sortOrder = $sorOrder;
        $this->raiseEvent(AdditionalOptionsSortOrderUpdated::create($this->id, $sorOrder));
    }
    
    
    /**
     * @return int
     */
    public function id(): int
    {
        return $this->id->value();
    }
    
    
    /**
     * @return int
     */
    public function productId(): int
    {
        return $this->productId->value();
    }
    
    
    /**
     * @return int|null
     */
    public function imageListId(): ?int
    {
        return $this->imageListId->value();
    }
    
    
    /**
     * @return int
     */
    public function optionId(): int
    {
        return $this->optionAndOptionValueId->optionId();
    }
    
    
    /**
     * @return int
     */
    public function optionValueId(): int
    {
        return $this->optionAndOptionValueId->optionValueId();
    }
    
    
    /**
     * @return int
     */
    public function sortOrder(): int
    {
        return $this->sortOrder;
    }
    
    
    /**
     * @return string
     */
    public function modelNumber(): string
    {
        return $this->optionValueCustomization->modelNumber();
    }
    
    
    /**
     * @return float
     */
    public function weight(): float
    {
        return $this->optionValueCustomization->weight();
    }
    
    
    /**
     * @return float
     */
    public function price(): float
    {
        return $this->optionValueCustomization->price();
    }
    
    
    /**
     * @return string
     */
    public function stockType(): string
    {
        return $this->additionalOptionStock->stockType();
    }
    
    
    /**
     * @return float
     */
    public function stock(): float
    {
        return $this->additionalOptionStock->stock();
    }
    
    
    /**
     * @return array
     */
    public function toArray(): array
    {
        return [
            'id'            => $this->id(),
            'imageListId'   => $this->imageListId(),
            'optionId'      => $this->optionId(),
            'optionValueId' => $this->optionValueId(),
            'sortOrder'     => $this->sortOrder(),
            'modelNumber'   => $this->modelNumber(),
            'weight'        => $this->weight(),
            'price'         => $this->price(),
            'stockType'     => $this->stockType(),
            'stock'         => $this->stock(),
        ];
    }
}